"""
模板管理API路由
提供模板的CRUD操作和模板提取功能
"""

from fastapi import APIRouter, HTTPException, Depends, Query
from fastapi.responses import JSONResponse
from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field
from datetime import datetime
from motor.motor_asyncio import AsyncIOMotorDatabase
import uuid

from ..core.database import get_db
from ..core.auth import get_current_user

router = APIRouter(prefix="/api/v1/templates", tags=["templates"])


# ========== Pydantic Models ==========

class TemplateVariable(BaseModel):
    """模板变量"""
    name: str
    description: str
    type: str = Field(default="text", pattern="^(text|number|date|select|textarea)$")
    required: bool = True
    defaultValue: Optional[str] = None
    options: Optional[List[str]] = None
    placeholder: Optional[str] = None


class Template(BaseModel):
    """模板数据模型"""
    id: Optional[str] = None
    name: str = Field(..., min_length=1, max_length=200)
    description: Optional[str] = None
    category: str = Field(..., pattern="^(news|product|tech|email|social|blog|marketing|academic|creative|business|other)$")
    content: str = Field(..., min_length=1)
    prompt: Optional[str] = None
    variables: List[TemplateVariable] = []
    tags: List[str] = []
    isPublic: bool = True
    language: str = "zh"
    usageCount: int = 0
    createdAt: Optional[datetime] = None
    updatedAt: Optional[datetime] = None
    authorId: Optional[str] = None
    lastUsedAt: Optional[datetime] = None


class TemplateCreate(BaseModel):
    """创建模板请求"""
    name: str
    description: Optional[str] = None
    category: str
    content: str
    prompt: Optional[str] = None
    variables: List[TemplateVariable] = []
    tags: List[str] = []
    isPublic: bool = True
    language: str = "zh"


class TemplateUpdate(BaseModel):
    """更新模板请求"""
    name: Optional[str] = None
    description: Optional[str] = None
    category: Optional[str] = None
    content: Optional[str] = None
    prompt: Optional[str] = None
    variables: Optional[List[TemplateVariable]] = None
    tags: Optional[List[str]] = None
    isPublic: Optional[bool] = None
    language: Optional[str] = None


class TemplateExtractRequest(BaseModel):
    """模板提取请求"""
    samples: List[str] = Field(..., min_items=1)
    type: str
    options: Optional[Dict[str, bool]] = None


# ========== Helper Functions ==========

def template_to_dict(template: Dict[str, Any]) -> Dict[str, Any]:
    """转换MongoDB文档为字典"""
    if template and "_id" in template:
        template["id"] = str(template["_id"])
        del template["_id"]
    return template


# ========== API Routes ==========

@router.get("", response_model=List[Template])
async def get_templates(
    category: Optional[str] = None,
    isPublic: Optional[bool] = None,
    tags: Optional[str] = None,
    query: Optional[str] = None,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """获取模板列表"""
    try:
        # 构建查询条件
        filter_query = {}

        if category:
            filter_query["category"] = category

        if isPublic is not None:
            filter_query["isPublic"] = isPublic

        if tags:
            tag_list = tags.split(',')
            filter_query["tags"] = {"$in": tag_list}

        if query:
            filter_query["$or"] = [
                {"name": {"$regex": query, "$options": "i"}},
                {"description": {"$regex": query, "$options": "i"}}
            ]

        # 查询模板
        cursor = db.templates.find(filter_query).sort("createdAt", -1)
        templates = await cursor.to_list(length=100)

        return [template_to_dict(t) for t in templates]

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取模板失败: {str(e)}")


@router.get("/my", response_model=List[Template])
async def get_my_templates(
    current_user: Dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """获取我的模板"""
    try:
        cursor = db.templates.find({"authorId": current_user["id"]}).sort("createdAt", -1)
        templates = await cursor.to_list(length=100)
        return [template_to_dict(t) for t in templates]

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取我的模板失败: {str(e)}")


@router.get("/public", response_model=List[Template])
async def get_public_templates(
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """获取公共模板"""
    try:
        cursor = db.templates.find({"isPublic": True}).sort("usageCount", -1)
        templates = await cursor.to_list(length=100)
        return [template_to_dict(t) for t in templates]

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取公共模板失败: {str(e)}")


@router.get("/popular", response_model=List[Template])
async def get_popular_templates(
    limit: int = Query(10, ge=1, le=50),
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """获取热门模板"""
    try:
        cursor = db.templates.find({"isPublic": True}).sort("usageCount", -1).limit(limit)
        templates = await cursor.to_list(length=limit)
        return [template_to_dict(t) for t in templates]

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取热门模板失败: {str(e)}")


@router.get("/{template_id}", response_model=Template)
async def get_template(
    template_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """获取单个模板"""
    try:
        template = await db.templates.find_one({"id": template_id})
        if not template:
            raise HTTPException(status_code=404, detail="模板不存在")

        return template_to_dict(template)

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取模板失败: {str(e)}")


@router.post("", response_model=Template)
async def create_template(
    template_data: TemplateCreate,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """创建模板"""
    try:
        # 生成模板ID
        template_id = f"template_{uuid.uuid4().hex[:16]}"

        # 构建模板文档
        template_doc = {
            "id": template_id,
            "name": template_data.name,
            "description": template_data.description,
            "category": template_data.category,
            "content": template_data.content,
            "prompt": template_data.prompt,
            "variables": [v.dict() for v in template_data.variables],
            "tags": template_data.tags,
            "isPublic": template_data.isPublic,
            "language": template_data.language,
            "usageCount": 0,
            "createdAt": datetime.utcnow(),
            "updatedAt": datetime.utcnow(),
            "authorId": None  # TODO: 从认证信息获取
        }

        # 插入数据库
        await db.templates.insert_one(template_doc)

        return template_to_dict(template_doc)

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建模板失败: {str(e)}")


@router.put("/{template_id}", response_model=Template)
async def update_template(
    template_id: str,
    update_data: TemplateUpdate,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """更新模板"""
    try:
        # 检查模板是否存在
        existing = await db.templates.find_one({"id": template_id})
        if not existing:
            raise HTTPException(status_code=404, detail="模板不存在")

        # 构建更新数据
        update_dict = {k: v for k, v in update_data.dict(exclude_unset=True).items() if v is not None}

        if update_dict:
            update_dict["updatedAt"] = datetime.utcnow()

            # 更新数据库
            await db.templates.update_one(
                {"id": template_id},
                {"$set": update_dict}
            )

        # 获取更新后的模板
        updated_template = await db.templates.find_one({"id": template_id})
        return template_to_dict(updated_template)

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新模板失败: {str(e)}")


@router.delete("/{template_id}")
async def delete_template(
    template_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """删除模板"""
    try:
        result = await db.templates.delete_one({"id": template_id})

        if result.deleted_count == 0:
            raise HTTPException(status_code=404, detail="模板不存在")

        return {"message": "模板已删除", "id": template_id}

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除模板失败: {str(e)}")


@router.post("/{template_id}/usage")
async def increment_usage(
    template_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """增加使用次数"""
    try:
        result = await db.templates.update_one(
            {"id": template_id},
            {
                "$inc": {"usageCount": 1},
                "$set": {"lastUsedAt": datetime.utcnow()}
            }
        )

        if result.modified_count == 0:
            raise HTTPException(status_code=404, detail="模板不存在")

        return {"message": "使用次数已更新"}

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新使用次数失败: {str(e)}")


@router.post("/{template_id}/duplicate", response_model=Template)
async def duplicate_template(
    template_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """复制模板"""
    try:
        # 获取原模板
        original = await db.templates.find_one({"id": template_id})
        if not original:
            raise HTTPException(status_code=404, detail="模板不存在")

        # 创建副本
        new_id = f"template_{uuid.uuid4().hex[:16]}"
        duplicate_doc = {
            **original,
            "id": new_id,
            "name": f"{original['name']} (副本)",
            "usageCount": 0,
            "createdAt": datetime.utcnow(),
            "updatedAt": datetime.utcnow(),
        }
        del duplicate_doc["_id"]

        # 插入数据库
        await db.templates.insert_one(duplicate_doc)

        return template_to_dict(duplicate_doc)

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"复制模板失败: {str(e)}")


@router.get("/stats/categories")
async def get_category_stats(
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """获取分类统计"""
    try:
        pipeline = [
            {"$group": {
                "_id": "$category",
                "count": {"$sum": 1}
            }}
        ]

        cursor = db.templates.aggregate(pipeline)
        stats = await cursor.to_list(length=None)

        return {item["_id"]: item["count"] for item in stats}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取统计失败: {str(e)}")
